/**
 * 
 */
package ee.fujitsu.utils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;

import ee.fujitsu.common.Printer;
import ee.fujitsu.common.Type;
import ee.fujitsu.entity.Customer;
import ee.fujitsu.entity.JournalRecord;
import ee.fujitsu.entity.state.Store;
import ee.fujitsu.factory.TypeFactory;

/**
 * The Class Orders.
 *
 * @author Andrei
 * 
 * 09.09.2012
 */
public class Orders {
	
	/**
	 * Bonus order.
	 *
	 * @param journal the journal
	 * @param store the store
	 * @param days the days
	 */
	public static void bonusOrder(
		Map<Integer, JournalRecord> journal, 
		Store store,
		int days) {
	Iterator<Entry<Integer, JournalRecord>> entries = journal.entrySet().iterator();
	Customer client = null;
	while (entries.hasNext()) {
		Entry<Integer, JournalRecord> thisEntry = (Entry<Integer, JournalRecord>) entries
				.next();
		JournalRecord record = thisEntry.getValue();
		if ((record.getCustomer().getBonus() >= 25) && (client == null))  {
				client = record.getCustomer();
				break;
		} 
	}
	if (client == null) {
		Printer.print("Cant find customer with bonus  > " + JournalRecord.BONUS_ACTION);
		return;
	}
	
	Date[] dates = Utils.getDates(days, 0);
	Date startDate = dates[0];
	Date expectedEnd = dates[1];
	Date realEnd = dates[2];

	JournalRecord record = store.rentFilm(startDate, expectedEnd, realEnd, client, true);
	
	if (record.isActiveBonus()) {
		Printer.print(record.getMovie().getTitle() + " ("
					+ Type.getTitle(record.getMovie().getType())
					+ ") "  + " (" + record.getBonusDays() + " days "
					+ " paid with "+ record.getBonusDays() * JournalRecord.BONUS_ACTION +" Bonus points) ");
	}
	Printer.print(record.getMovie().getTitle() + " ("
			+ Type.getTitle(record.getMovie().getType())
			+ ") "  + (record.dayDifference() - record.getBonusDays()) + " days "
			+ record.getFpayment() + " EUR");
	Printer.print("Total price : " + record.getFpayment() + " EUR");
	if (record.isActiveBonus())
		Printer.print("Remaining Bonus points: (" + record.getCustomer().getName() + ") " + record.getCustomer().getBonus());
		
		
	}

		/**
		 * Late order.
		 *
		 * @param journal the journal
		 * @param store the store
		 * @param daysQty the days qty
		 */
	public static void lateOrder(
			Map<Integer, JournalRecord> journal,
			Store store,
			int daysQty) {
		List<JournalRecord> records = new ArrayList<JournalRecord>();
		Iterator<Entry<Integer, JournalRecord>> entries = journal.entrySet().iterator();
		Customer client = null;
		while (entries.hasNext()) {
			Entry<Integer, JournalRecord> thisEntry = (Entry<Integer, JournalRecord>) entries
					.next();
			JournalRecord record = thisEntry.getValue();
			if ((record.getSpayment() == 0.0) && (client == null))  {
					records.add(record);
					client = record.getCustomer();
			} else if ((record.getSpayment() == 0.0) &&  client == record.getCustomer())
				records.add(record);
			else if ((client != null) && ((record.getSpayment() != 0.0) || client != record.getCustomer()))
					break;
		}
		double total = 0.0;
		for (JournalRecord journalRecord : records) {
			Calendar cal = Calendar.getInstance();
		    cal.setTime(journalRecord.getExpectedEnd());
		    cal.add(Calendar.DATE, daysQty); 
		    Date realEnd = cal.getTime();

			TypeFactory factory = new TypeFactory();
			factory.updateRecord(journalRecord, realEnd);
			store.returnFilm();
			Printer.print(journalRecord.getMovie().getTitle() + " ("
					+ Type.getTitle(journalRecord.getMovie().getType())
					+ ") " + journalRecord.dayOverhead() + " extra days "
					+ journalRecord.getSpayment() + " EUR");
			total += journalRecord.getSpayment();
		}
		Printer.print("Total late charge: " + total + " EUR");
	}

		/**
		 * Adds the order.
		 *
		 * @param customers the customers
		 * @param store the store
		 * @param filmQty the film qty
		 * @param days the days
		 */
	public static void addOrder(
			Map <Integer, Customer> customers,
			Store store,
			int filmQty, int days) {
		List<JournalRecord> records = new ArrayList<JournalRecord>();
		List<Integer> customerIndexes = new ArrayList<Integer>(
				customers.keySet());
		int cind = customerIndexes.get(new Random().nextInt(customerIndexes
				.size() - 1));
		Customer client = customers.get(cind);
		Date[] dates = Utils.getDates(days, 0);
		Date startDate = dates[0];
		Date expectedEnd = dates[1];
		Date realEnd = dates[2];
		for (int i = 0; i < filmQty; i++) {
			JournalRecord record = store.rentFilm(startDate, expectedEnd, realEnd, client, true);
			records.add(record);
		}
		double total = 0.0;
		for (JournalRecord record : records) {
			Printer.print(record.getMovie().getTitle() + " ("
					+ Type.getTitle(record.getMovie().getType())
					+ ") " + record.dayDifference() + " days "
					+ record.getFpayment() + " EUR");
			total += record.getFpayment();
		}
		Printer.print("Total price : " + total + " EUR");
	}

}
